﻿

using Controller.i18n.entity;
using HBase;
using hCommand;
using hconnect; 
using System;
using System.Collections.Generic; 

namespace Controller {


    public abstract class CraneAllocateJobCache:AbsCraneJjlAllocate {
        TaskDir craneDir = TaskDir.前进; 
        public override BaseTask analyseSingleTaskModel(CraneStatus craneStatus,      List<TaskCrane> tclist ) { 
            int X = craneStatus.x;
            List<TaskCrane> currentTask = getCurrentTask( tclist, X);
            if (currentTask.Count > 0) {
                var res= atStn(currentTask,craneStatus);
                if(res!=null){ 
                    return res;    
                }
            } 
            CraneTaskSplit split = splitTasks(tclist,X);
            bool change = opDir(split,tclist,craneStatus);
            if (change) {
                split = splitTasks(tclist,X);
            }
            tclist = split.willDoneList;
            carrierRemove(tclist);

            if (tclist.Count == 0) {
                return onlyMissing(split.missList);
            } else {
                return priorityOut(tclist);
            }
           
        }

        List<TaskCrane> getCurrentTask(  List<TaskCrane> tclist,int X){
               List<TaskCrane> currentTask = new List<TaskCrane>();
              foreach (TaskCrane crane in tclist) {
                
                if (crane.step == 1 && crane.sx == X || crane.step == 2 && crane.dx == X) {
                    currentTask.Add(crane);
                }
            }
            return currentTask;
         }

        TaskCrane onlyMissing(List<TaskCrane> missList) {
            TaskCrane selectTc = null;
            foreach (TaskCrane t in missList) {
                if (selectTc == null) {
                    selectTc = t;
                    continue;
                }
                int selectX = selectTc.step == 1 ? selectTc.sx : selectTc.dx;
                int x2 = t.step == 1 ? t.sx : t.dx;
                if (craneDir == TaskDir.前进) {
                    if (selectX > x2) {
                        selectTc = t;
                    }
                } else {
                    if (selectX < x2) {
                        selectTc = t;
                    }
                }
            }
            return selectTc;
        }


        CraneTaskSplit splitTasks(List<TaskCrane> tclist,int X) {
            var res = new CraneTaskSplit();
            foreach (TaskCrane tc in tclist) {
                if (tc.step == 2) { //在缓存
                    var dir = tc.getStep2Dir(X);
                    if (dir == craneDir || TaskDir.原位 == dir) {
                        res.willDoneList.Add(tc);
                    } else {
                        res.reverseList.Add(tc);
                    }
                    continue;
                }
                TaskDir endDir = tc.getStep1Dir();
                TaskDir firstDir = tc.changeDir(X,tc.sx);


                if (craneDir == TaskDir.前进) {
                    if (firstDir == TaskDir.前进 || firstDir == TaskDir.原位) {
                        if (endDir == TaskDir.前进 || endDir == TaskDir.原位) {
                            res.willDoneList.Add(tc);
                        } else {
                            res.reverseList.Add(tc);
                        }
                    } else {
                        if (endDir == TaskDir.前进 || endDir == TaskDir.原位) {
                            res.missList.Add(tc);
                        } else {
                            res.reverseList.Add(tc);
                        }
                    }
                } else {
                    if (firstDir == TaskDir.后退 || firstDir == TaskDir.原位) {
                        if (endDir == TaskDir.后退 || endDir == TaskDir.原位) {
                            res.willDoneList.Add(tc);
                        } else {
                            res.reverseList.Add(tc);
                        }
                    } else {
                        if (endDir == TaskDir.后退 || endDir == TaskDir.原位) {
                            res.missList.Add(tc);
                        } else {
                            res.reverseList.Add(tc);
                        }
                    }
                }
            }
            return res;

        }
        public override bool chechModeDB() {
            BParam p = MyCache.getValue<BParam>(getCNo());
            if (p == null) {
                console(InfoC.consol_Crane_overStop,"垛机配置异常" + getCNo());
                return false;
            }
            //验证垛机mechine_status 表中overstop 位1 代表循环停止
            if (p.v == 1) {
                console(InfoC.consol_Crane_overStop,"垛机循环停止");
                return false;
            }
            return true;
        } 
        TaskCrane atStn(List<TaskCrane> tclist,CraneStatus craneStatus) {
            bool has = false;
            CarrierSignalStatus ssIn1 = StatusCache.getSignalStatus<CarrierSignalStatus>(11);
            int cacheCout = 0;
            if (ssIn1 == null || !ssIn1.isArrived()) {

                foreach (TaskCrane crane in tclist) {

                    if (crane.sx == craneStatus.x) {
                        has = true;
                        if (crane.taskNo == ssIn1.no) {
                            return crane;
                        }
                    }
                    if (crane.sx > 100 && crane.sx < 10000) { //垛机上的缓存数量
                        cacheCout++;
                    }
                }
            }
            CarrierSignalStatus ssOut1 = StatusCache.getSignalStatus<CarrierSignalStatus>(21);
            if (ssOut1 == null && ssOut1.isFree()) {
                foreach (TaskCrane crane in tclist) {
                    if (crane.dx == craneStatus.x) {
                        has = true;
                        if (crane.des == 21) {
                            return crane;
                        }
                    }
                }
            }
            return null;
        }
        bool opDir(CraneTaskSplit split,List<TaskCrane> tclist,CraneStatus craneStatus) {
            if (split.willDoneList.Count > 0) {
                return false;
            }
            if (split.reverseList.Count > 0) {
                craneDir = TaskDir.前进 == craneDir ? TaskDir.后退 : TaskDir.前进;
                return true;
            }
            return false;
        }
        TaskCrane priorityOut(List<TaskCrane> tclist) {
            int count = 0;
            TaskCrane taskCrane = null;
            foreach (TaskCrane ct in tclist) {
                if (ct.priority > 0) {
                    count++;
                    if (taskCrane == null || taskCrane.priority < ct.priority) {
                        taskCrane = ct;
                    }
                }
            }
            consoleOnly(InfoC.consoleOnly_crane_Working,"优先可执行任务数" + count);
            return taskCrane;
        }
        public void carrierRemove(List<TaskCrane> allFtList) {
            List<TaskCrane> removeList = new List<TaskCrane>(); 
            foreach (TaskCrane ft in allFtList) {
                if (!I18nConfig.isLoc(ft.des)) { 
                        consoleOnly(InfoC.consoleOnly_crane_Working,getCNo() + "禁止出库");
                        removeList.Add(ft); 
                }
                if (!I18nConfig.isLoc(ft.src)) {
                    int p = Math.Abs(ft.src);
                    int count = 0;
                    foreach (TaskCrane tc in allFtList) {
                        if (tc.src == p) {
                            count++;
                        }
                    }
                    if (count > 1) {
                        removeList.Add(ft);
                        consoleOnly(InfoC.consoleOnly_crane_Working,p + "入库任务过多");
                    }

                    CarrierSignalStatus ssIn1 = StatusCache.getSignalStatus<CarrierSignalStatus>(p);

                    if (ssIn1 == null || !ssIn1.isArrived()) {
                        consoleOnly(InfoC.consoleOnly_crane_Working,p + "异常或者，输送线不允许取料");
                        removeList.Add(ft);
                    }
                }
            }
            foreach (TaskCrane ft in removeList) {
                if (allFtList.Contains(ft)) {
                    allFtList.Remove(ft);
                }
            }
        }
    }

    public class CraneTaskSplit {
        public List<TaskCrane> missList = new List<TaskCrane>();
        public List<TaskCrane> reverseList = new List<TaskCrane>();
        public List<TaskCrane> willDoneList = new List<TaskCrane>();
    }
}
